上篇我們了解 setState 為非同步,而此篇將會舉一個setState踩雷的例子並且告訴大家如何改進。
上篇程式碼,當我們按了按鈕一次,UI 數字就會跟著 +1
increment() {
this.setState({
count: this.state.count + 1
});
}
render() {
return (
<div>
<div>counter - {this.state.count}</div>
<button onClick={() => this.incrementFive()}>button</button>
</div>
)
}
把新增的 increment 方法放進 function FiveIncrement 呼叫五次
increment() {
this.setState({
count: this.state.count + 1
},
() => {
console.log('callback value', this.state.count)
})
console.log(this.state.count);
}
incrementFive() {
this.increment();
this.increment();
this.increment();
this.increment();
this.increment();
}
render() {
return (
<div>
<div>counter - {this.state.count}</div>
<button onClick={() => this.incrementFive()}>button</button>
</div>
)
}
}
預期按按鈕一次等於呼叫五次應該得到數字5,為何卻得到數字 1?

React 可以將多個
setState()呼叫批次處理為單一的更新,以提高效能。
什麼意思呢?
以上方程式碼舉例: incrementFive(),React為了提高效能,只會呼叫一次 setState()也就是只呼叫一次increment(),因此數字才會只增加 1。
用 preState 取得上一個 state,而不是用 this.state。
increment() {
this.setState(prevState => ({
count: prevState.count + 1
}))
console.log(this.state.count);
}

程式碼大概會長以下這樣:
this.setState((prevState, props) => ({
count: prevState.count + addValue(props)
}))
此篇其實是在一個 youtube 看到的範例,過去沒有發現是因為我都把 setState 這個動作當作一個聰明的組件在執行 ; 同時也會新增一個笨的組件當作 UI 的部分。
以目前我們公司專案,會有以下兩個組件:
SmartCounter.js 做較複雜的動作 ex. setStateDumbCounter.js 簡單的動作 ex. UI 呈現DumbCounter 會接收來自 SmartCounter 的 setState 資料,且因為是由上而下的資料流,此時子組件的DumbCounter 會把來自父組件 SmartCounter 的 state 的資料變成 props,近而比較好利用。